package com.luqili.utils.pub.rest.param;

import cn.hutool.core.convert.Convert;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.ArrayUtil;
import cn.hutool.core.util.ClassUtil;
import cn.hutool.core.util.StrUtil;
import com.luqili.utils.pub.base.LuException;
import com.luqili.utils.pub.base.LuUserInputException;
import com.luqili.utils.pub.date.DateUtilsExt;
import com.luqili.utils.pub.link.Pair;
import com.luqili.utils.pub.sql.LuAutoPageParams;
import com.luqili.utils.pub.sql.LuAutoPageResult;
import com.luqili.utils.pub.sql.LuAutoPageUtils;
import org.apache.commons.lang3.StringUtils;

import java.util.Date;
import java.util.List;

public abstract class LuBasePageParams extends LuParams {

    /**
     * 预制查询条件：类型
     *
     * @return Integer | null
     */
    public Integer getType() {
        return getInt("type");
    }

    /**
     * 预制查询条件：状态
     *
     * @return Integer | null
     */
    public Integer getStatus() {
        return getInt("status");
    }


    /**
     * 预制查询条件：子类型
     *
     * @return Integer | null
     */

    public Integer getSubType() {
        return getInt("subType");
    }


    /**
     * 通用的模糊查询条件
     *
     * @return String
     */
    public String getSearch() {
        return Convert.toStr(get("search"));
    }


    /**
     * 设置模糊查询条件
     *
     * @param search 字符串
     */
    public void setSearch(String search) {
        this.put("search", search);
    }

    /**
     * 自动添加%号
     *
     * @return String
     */
    public String getSearchLike() {
        String search = this.getSearch();
        if (StringUtils.isNotBlank(search)) {
            return "%" + search.trim() + "%";
        }
        return null;
    }

    /**
     * 获取当前页码
     *
     * @return
     */
    public Integer getCurrent() {
        return getInt("current", 1);
    }

    public void setCurrent(Integer current) {
        put("current", current);
    }

    /**
     * 获取分页大小
     *
     * @return
     */
    public Integer getPageSize() {
        return getInt("pageSize", 20);
    }

    /**
     * 设置分页大小
     *
     * @param pageSize
     */
    public void setPageSize(Integer pageSize) {
        put("pageSize", pageSize);
    }

    /**
     * 获取查询时间段
     *
     * @param beforeDay 默认时间段间隔天数
     * @return
     */
    public Pair<Date, Date> getSearchDate(Integer beforeDay) {
        String searchDate = this.getStr("searchDate");
        if (StringUtils.isBlank(searchDate)) {
            searchDate = this.getStr("searchDate");
        }
        String startDateStr = "", endDateStr = "";
        if (StringUtils.isNotBlank(searchDate)) {
            String[] ds = searchDate.split("~");
            if (ds.length > 1) {
                startDateStr = ds[0].trim();
                endDateStr = ds[1].trim();
            }
        } else {
            startDateStr = this.getStr("startDate");
            endDateStr = this.getStr("endDate");
        }
        Date startDate = DateUtilsExt.parseDate(startDateStr);
        Date endDate = DateUtilsExt.parseDate(endDateStr);
        if (endDate == null) {
            endDate = DateUtilsExt.getEndDay(new Date());
        }
        if (startDate == null) {
            startDate = DateUtilsExt.getStartDay(endDate, beforeDay == null ? -7 : -Math.abs(beforeDay));
        }
        return new Pair<>(startDate, endDate);
    }

    /**
     * 排序字段
     *
     * @return
     */
    public abstract String getSortKey();

    /**
     * 排序类型
     * ase desc
     *
     * @return
     */
    public abstract String getSortType();

    /**
     * 获取安全的OrderBy的SQL语句
     *
     * @param defaultField 默认排序字段，为空时根据安全类自动判断
     * @param ca           安全实体Bean
     * @return
     */
    public String orderBy(String defaultField, Class ca) {
        if (StringUtils.isBlank(defaultField)) {
            if (ClassUtil.getDeclaredField(ca, "sort") != null) {
                defaultField = "sort";
            }
        }
        if (StringUtils.isBlank(defaultField)) {
            if (ClassUtil.getDeclaredField(ca, "id") != null) {
                defaultField = "id";
            }
        }
        if (StringUtils.isBlank(defaultField)) {
            if (ClassUtil.getDeclaredField(ca, "createTime") != null) {
                defaultField = "createTime";
            }
        }
        if (StringUtils.isBlank(defaultField)) {
            if (ClassUtil.getDeclaredField(ca, "upTime") != null) {
                defaultField = "upTime";
            }
        }
        StringBuilder orderBy = new StringBuilder();
        String sort = getSortKey();
        if (StringUtils.isNotBlank(sort) && !sort.equals(defaultField)) {
            if (ClassUtil.getDeclaredField(ca, sort) != null) {
                orderBy.append(StrUtil.toUnderlineCase(sort)).append(" ").append(getSortType()).append(",");
            }
        }
        if (StringUtils.isNotBlank(defaultField)) {
            orderBy.append(StrUtil.toUnderlineCase(defaultField)).append(" ").append(sort.equals(defaultField) ? getSortType() : "desc");
        }
        return orderBy.toString();

    }

    /**
     * 获取排序SQL
     *
     * @param fields 指定排序范围,第一个为默认排序
     * @return
     */
    public String orderBy(String... fields) {
        if (fields == null || fields.length < 1) {
            throw new LuException("未指定排序字段范围");
        }
        StringBuilder orderBy = new StringBuilder();
        String sort = getSortKey().trim();
        if (ArrayUtil.contains(fields, sort) && !sort.equals(fields[0])) {
            orderBy.append(sort).append(" ").append(getSortType()).append(",");
        } else if (sort.endsWith("Name")) {
            //带有Name结尾的自动转义
            sort = StringUtils.removeEnd(sort, "Name");
            if (ArrayUtil.contains(fields, sort) && !sort.equals(fields[0])) {
                orderBy.append(sort).append(" ").append(getSortType()).append(",");
            }
        }
        orderBy.append(fields[0]).append(" ").append(sort.equals(fields[0]) ? getSortType() : "desc");
        return orderBy.toString();
    }

    /**
     * 获取日期段，默认7天
     *
     * @param beforeDay
     * @param maxDay
     * @return
     */
    public Pair<Date, Date> getDateRange(Integer beforeDay, Integer maxDay) {
        return getDateRange("dateRange", beforeDay, maxDay);
    }

    /**
     * 获取日期段，默认7天
     *
     * @param beforeDay 正数为几天前，复数为几天后
     * @param maxDay    为空不限制
     * @return
     */
    public Pair<Date, Date> getDateRange(String fieldName, Integer beforeDay, Integer maxDay) {
        List<Date> dateRange = this.getListDate(fieldName);
        Date startDate = null;
        Date endDate = null;
        if (dateRange != null && dateRange.size() > 0) {
            startDate = dateRange.get(0);
            if (dateRange.size() > 1) {
                endDate = dateRange.get(1);
            }
        }
        if (endDate == null) {
            endDate = DateUtil.endOfDay(new Date());
        }

        if (startDate == null) {
            startDate = DateUtil.beginOfDay(DateUtil.offsetDay(endDate, beforeDay == null ? -7 : -beforeDay));
        }
        if (endDate.getTime() < startDate.getTime()) {
            //交换顺序
            Date d1 = startDate;
            startDate = endDate;
            endDate = d1;
        }
        if (maxDay != null && DateUtil.betweenDay(startDate, endDate, false) > maxDay) {
            throw new LuUserInputException("时间段相差不能超过" + maxDay + "天");
        }
        return new Pair(startDate, endDate);
    }

    /**
     * 自动分页功能
     *
     * @param dbBean
     * @param params
     * @return
     */
    public LuAutoPageResult autoPageResult(Class dbBean, LuAutoPageParams params) {
        return LuAutoPageUtils.autoPage(dbBean, this, params);
    }

}
